/**
 * 
 */
package com.greenx.hello.hThread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author StephenXianweiZhang
 * 
 */
public class HelloMultiThreads {

	public static void run() {
		HelloMultiThreads helloMultiThreads = new HelloMultiThreads();
		helloMultiThreads.testMultiThreads();
		// helloMultiThreads.releaseResource();

	}

	private void init() {

		for (int i = 0; i < 9942; i++) {
			usersList.add("str:" + i);
		}
	}

	private List<String> usersList = new ArrayList<String>();
	private BlockingQueue<Runnable> worksQueue = null;
	private RejectedExecutionHandler executionHandler = null;
	private ThreadPoolExecutor executor = null;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloMultiThreads.run();
	}

	private void testMultiThreads() {
		init();
		int threadBasedHandleSize = 256;
		// int maxLoop = getMaxLoop(usersList, threadBasedHandleSize);
		// System.out.println("maxLoop:" + maxLoop);
		// worksQueue = new ArrayBlockingQueue<Runnable>(maxLoop);
		// executionHandler = new PassPolicyRejectedExecutionHandler();
		// executor = new ThreadPoolExecutor(0, 8, 10, TimeUnit.SECONDS,
		// worksQueue, executionHandler);
		// for (int i = 0; i < maxLoop; i++) {
		// executor.execute(new MultiThreadTesting(getUsersListPerThread(
		// usersList, threadBasedHandleSize, i)));
		// }

		try {
			int maxLoop = getMaxLoop(usersList, threadBasedHandleSize);
			BlockingQueue<Runnable> worksQueue = new ArrayBlockingQueue<Runnable>(
					maxLoop);
			RejectedExecutionHandler executionHandler = new PassPolicyRejectedExecutionHandler();
			ThreadPoolExecutor executor = new ThreadPoolExecutor(0, 8, 64,
					TimeUnit.SECONDS, worksQueue, executionHandler);
			List<String> usersListTemp = null;
			MultiThreadsTesting multiThreadsTesting = null;
			for (int i = 0; i < maxLoop; i++) {

				usersListTemp = getUsersListPerThread(usersList,
						threadBasedHandleSize, i);
				if (maxLoop - i == 1) {
					// executor.execute(new MultiThreadTesting(usersListTemp,
					// true));
					multiThreadsTesting = new MultiThreadsTesting(
							usersListTemp, true);
					multiThreadsTesting.start();
				} else {
					// executor.execute(new MultiThreadTesting(usersListTemp,
					// false));
					multiThreadsTesting = new MultiThreadsTesting(
							usersListTemp, true);
					multiThreadsTesting.start();
				}
			}
		} catch (Exception e) {

		}

	}

	private void releaseResource() {
		if (executor.getActiveCount() == 0) {
			// executor.shutdownNow();
		}
	}

	private static int getMaxLoop(List<String> usersList,
			int threadBasedHandleSize) {
		int maxLoop = 0;

		if (usersList.size() > 0) {
			maxLoop = usersList.size() / threadBasedHandleSize + 1;
		}
		return maxLoop;
	}

	private static List<String> getUsersListPerThread(List<String> usersList,
			int threadBasedHandleSize, int times) {
		int maxLoop = getMaxLoop(usersList, threadBasedHandleSize);
		List<String> usersListTmp = new ArrayList<String>();
		System.out.println(usersList.size() + "|" + threadBasedHandleSize + "|"
				+ times);
		if (times == 0) {
			usersListTmp = usersList.subList(0, threadBasedHandleSize);
		} else if (times == (maxLoop - 1)) {
			usersListTmp = usersList.subList(threadBasedHandleSize,
					usersList.size());
		} else {
			usersListTmp = usersList.subList(threadBasedHandleSize,
					threadBasedHandleSize * (times + 1));
		}
		return usersListTmp;
	}

	private void sysout(String str) {
		System.out.println("String:" + str);
	}

	private class MultiThreadTesting implements Runnable {

		List<String> usersList = null;
		private boolean stopRequested = false;

		public MultiThreadTesting(List<String> usersList, boolean outputTime) {
			this.usersList = usersList;
		}

		@Override
		public void run() {
			// if (!stopRequested) {
			for (String str : usersList) {
				// if (str.indexOf("6900") > 0) {
				sysout(str);
				// }
			}
			stopRequested = true;
			// }
			System.out.println("stopRequested:" + stopRequested);
		}

	}

	private class MultiThreadsTesting extends Thread {

		List<String> usersList = null;
		private boolean stopRequested = false;

		public MultiThreadsTesting(List<String> usersList, boolean outputTime) {
			this.usersList = usersList;
		}

		@Override
		public void run() {
			if (!stopRequested) {
				long startTimeMs = System.currentTimeMillis();
				for (String str : usersList) {
					// if (str.indexOf("6900") > 0) {
					sysout(str);
					// }
				}
				stopRequested = true;
				long taskTimeMs = System.currentTimeMillis() - startTimeMs;
				System.out.println("stopRequested:" + stopRequested
						+ " taskTimeMs:" + taskTimeMs);
			}

		}

	}

}
